package org.example.server;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import org.example.Model.RequestData;
import org.example.Model.ResponseData;
import org.example.RPCApplication;
import org.example.registry.Registry;
import org.example.serialize.JdkSerializer;
import org.example.serialize.Serializer;
import org.example.serialize.SerializerFactory;

import java.io.IOException;
import java.lang.reflect.Method;

public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest event) {
        // 指定序列化器
//        final Serializer serializer = new JdkSerializer();
        final Serializer serializer = SerializerFactory.getInstance(RPCApplication.getConfig().getSerializer());
        // 记录日志
        System.out.println("=============HttpServerHandler receive request from " + event.remoteAddress());
        // 读取请求数据
        event.bodyHandler(buffer -> {
            RequestData requestData = null;
            try {
                // 反序列化请求数据
                requestData = serializer.deserialize(buffer.getBytes(), RequestData.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 处理请求数据
            ResponseData responseData = new ResponseData();
            if(requestData == null) {
                responseData.setMessage("error");
                doResponse(event,responseData,serializer);
                return;
            }
            // 获取要调用的实例，通过反射实现
            try {
                System.out.println("获取服务实例：" + requestData.getServiceName());
                Class<?> aClass = Registry.get(requestData.getServiceName());
                Method method = aClass.getMethod(requestData.getMethodName(), requestData.getParameterTypes());
                Object invoke = method.invoke(aClass.newInstance(), requestData.getArgs());
                // 封装结果
                responseData.setData(invoke);
                responseData.setDataType(invoke.getClass());
                responseData.setMessage("success");
            } catch (Exception e) {
                e.printStackTrace();
            }
            doResponse(event,responseData,serializer);
        });
    }

    private void doResponse(HttpServerRequest event, ResponseData responseData, Serializer serializer) {
        try {
            event.response().putHeader("Content-Type", "application/json")
                    .end(Buffer.buffer(serializer.serialize(responseData)));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
